﻿using TestingConcurrencyBenchmark.Helpers;

namespace TestingConcurrencyBenchmark.Problems.DiningPhilosophers.Philosophers
{
    /// <summary>
    /// An abstraction of a Philosopher
    /// 
    /// A Philosopher has a left fork and a right fork, represented by Semaphores
    /// It has to be able to get forks and put forks, hence those two methods have been provided.
    /// </summary>
    public abstract class AbstractPhilosopher
    {
        /// <summary>
        /// The Philosopher's left fork
        /// </summary>
        protected BenchmarkSemaphore LeftFork;

        /// <summary>
        /// The Philosopher's right fork
        /// </summary>
        protected BenchmarkSemaphore RightFork;

        /// <summary>
        /// Creates a new Philosopher and initializes its forks
        /// | new.LeftFork == leftFork
        /// | new.RightFork = rightFork
        /// </summary>
        /// 
        /// <param name="leftFork">the Philosopher's new left fork</param>
        /// <param name="rightFork">the Philosopher's new right fork</param>
        protected AbstractPhilosopher(BenchmarkSemaphore leftFork, BenchmarkSemaphore rightFork)
        {
            LeftFork = leftFork;
            RightFork = rightFork;
        }

        /// <summary>
        /// Makes the Philosopher "pick up" the forks
        /// calls LeftFork.WaitOne() and RightFork.WaitOne()
        /// The order in which they are called depends on the implementation
        /// </summary>
        public abstract void GetForks();

        /// <summary>
        /// Makes the Philosopher "put down" the forks
        /// calls LeftFork.Release() and RightFork.Release()
        /// The order in which they are called depends on the implementation
        /// </summary>
        public abstract void PutForks();
    }
}